package org.eoti.rei;

/**
 * The MIT License
 * <p/>
 * Copyright (c) 2009 Malachi de AElfweald (malachid@gmail.com)
 * <p/>
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * <p/>
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 * Software.
 * <p/>
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.eoti.io.console.Terminal;
import org.eoti.io.xls.XLSReader;
import org.eoti.rei.ndfcmd.NDFBrowserCommand;

import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.util.*;

public class NDFBrowser
	extends Terminal
{
	private static ServiceLoader<NDFBrowserCommand> commandServiceLoader = ServiceLoader.load(NDFBrowserCommand.class);
	protected HashMap<String, NDFBrowserCommand> commands;
	protected boolean done = false;
	protected XLSReader reader;

	public static void main(String[] args)
	{
		try{
			NDFBrowser browser = new NDFBrowser();
		} catch(Exception e){
			// IntelliJ is incorrectly reporting an error here...
			System.err.format("Error: %s\n", e.getMessage());
			e.printStackTrace();
		}
	}

	public NDFBrowser()
			throws IOException
	{
		super();
		commands = new HashMap<String, NDFBrowserCommand>();
		for(NDFBrowserCommand cmd : commandServiceLoader)
			install(cmd);

		start();
	}

	public void report()
	{
		if(reader == null)
		{
			format("No data loaded. Try 'load filename'.\n");
			return;
		}
		format("%s houses found.\n", reader.rows().size());
	}

	public XLSReader getReader()
	{
		return reader;
	}

	public void reset()
	{
		if(reader == null)
		{
			format("No data loaded. Try 'load filename'.\n");
			return;
		}
		reader.reset();
		report();
	}

	public Date getAuctionDateTime(int row)
	{
		if(reader == null)
		{
			format("No data loaded. Try 'load filename'.\n");
			return null;
		}

		Calendar c1 = Calendar.getInstance();
		c1.setTime((Date)(reader.getColumn("Foreclosure Auction Date").getValue(row)));

		Calendar c2 = Calendar.getInstance();
		c2.setTime((Date)(reader.getColumn("Foreclosure Auction Time").getValue(row)));

		c1.set(Calendar.HOUR, c2.get(Calendar.HOUR));
		c1.set(Calendar.MINUTE, c2.get(Calendar.MINUTE));
		c1.set(Calendar.AM_PM, c2.get(Calendar.AM_PM));

		return c1.getTime();
	}

	public void load(File file)
			throws IOException
	{
		if(reader != null)
		{
			format("Previous data already loaded. Replacing with new data.\n");
			return;
		}
		reader = new XLSReader(file);
		report();
	}

	public void remove(HSSFRow row)
	{
		if(reader == null)
		{
			format("No data loaded. Try 'load filename'.\n");
			return;
		}
		reader.remove(row);
	}

	public void remove(int row)
	{
		if(reader == null)
		{
			format("No data loaded. Try 'load filename'.\n");
			return;
		}
		reader.remove(row);
	}

	public void install(NDFBrowserCommand command)
	{
		command.setBrowser(this);
		for(String cmdName : command.commands())
			commands.put(cmdName.toLowerCase(), command);
	}

	public HashMap<String, NDFBrowserCommand> commands(){return commands;}

	public void start()
	{
		while(!done)
		{
			List<String> args = promptArgs();
			if(args.size() == 0) continue;
			try{
				NDFBrowserCommand cmd = commands.get(args.get(0).toLowerCase());
				if(cmd == null)
				{
					format("Command unknown: %s\n", args.get(0));
					continue;
				}

				args.remove(0);
				cmd.process(args);
			} catch(Exception e){
				error(e, false);
			}
		}
	}

	public void stop()
	{
		done = true;
	}

	public String readLine(String fmt, Object... args)
	{
		return super.readLine(fmt, args);
	}

	public Console format(String fmt, Object ... args)
	{
		return super.format(fmt, args);
	}
}
